package xyz.mumuwei.youthcourseserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import xyz.mumuwei.youthcourseserver.common.dto.PageDto;
import xyz.mumuwei.youthcourseserver.common.lang.Const;
import xyz.mumuwei.youthcourseserver.common.lang.Result;
import xyz.mumuwei.youthcourseserver.exception.CommonException;
import xyz.mumuwei.youthcourseserver.mapper.*;
import xyz.mumuwei.youthcourseserver.pojo.*;
import xyz.mumuwei.youthcourseserver.service.CourseService;
import xyz.mumuwei.youthcourseserver.utils.TimeUtil;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author mumuwei
 * @since 2022-02-19
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements CourseService {

    final CourseMapper courseMapper;
    final CourseTimeMapper timeMapper;
    final FileResourcesMapper fileMapper;
    final UserInfoMapper teacherMapper;
    final TeacherMapper courseTeacherMapper;
    final CourseRotationMapper rotationMapper;
    final OrderMapper orderMapper;


    /**
     * 课程列表-分页
     * @param uid 用户id
     * @param pageDto 分页参数
     */
    @Override
    public Result getCoursePage(PageDto pageDto, Integer uid) {
        pageDto.setStart((pageDto.getCurrent()-1)*pageDto.getSize());
        pageDto.setEnd(pageDto.getCurrent()*pageDto.getSize());
        UserInfo userInfo = teacherMapper.selectOne(new QueryWrapper<UserInfo>().eq("user_id", uid));
        if(Const.TEACHER_ROLE_CODE.equals(userInfo.getRoleId())) {
            // 教师
            pageDto.setId(userInfo.getId());
        } else {
            // 管理员
            pageDto.setId(null);
        }
        List<Course> list = courseMapper.getCoursePage(pageDto);
        Page<Course> coursePage = new Page<>(pageDto.getCurrent(), pageDto.getSize());
        coursePage.setRecords(list);
        if(list.size() <= 0) {
            coursePage.setTotal(0);
            return Result.success(coursePage);
            // return Result.fail("课程数据为空！");
        }
        if(!"".equals(pageDto.getKey())) {
            coursePage.setTotal(courseMapper.selectCount(new QueryWrapper<Course>().like("name", pageDto.getKey())));
        } else {
            coursePage.setTotal(courseMapper.selectCount(new QueryWrapper<>()));
        }
        return Result.success(coursePage);
    }

    /**
     * 根据课程分类获取分页课程列表
     *
     * @param pageDto 分类参数
     * @return 返回数据
     */
    @Override
    public Result getPageByType(PageDto pageDto) {
        pageDto.setStart((pageDto.getCurrent()-1)*pageDto.getSize());
        pageDto.setEnd(pageDto.getCurrent()*pageDto.getSize());
        List<Course> list = courseMapper.getCoursePageByClass(pageDto);
        if(list.size() <= 0) {
            return Result.fail("课程数据为空！");
        }
        Page<Course> coursePage = new Page<>(pageDto.getCurrent(), pageDto.getSize());
        coursePage.setRecords(list);
        if(!"".equals(pageDto.getKey())) {
            coursePage.setTotal(courseMapper.selectCount(new QueryWrapper<Course>().eq("classify", pageDto.getKey())));
        } else {
            coursePage.setTotal(courseMapper.selectCount(new QueryWrapper<>()));
        }
        return Result.success(coursePage);
    }

    /**
     * 根据课程 Id 删除课程信息
     *
     * @param id 课程 Id
     * @return 删除结果
     */
    @Override
    public Result deleteCourseById(Integer id) {
        // 1、删除课程信息
        int i = courseMapper.deleteById(id);

        // 2、删除课程关联教师
        courseTeacherMapper.deleteByCourseId(id);

        // 3、删除课程关联课时信息
        timeMapper.delete(new QueryWrapper<CourseTime>().eq("course_id", id));

        // 4、删除课程关联轮播图信息
        // 4.1 获取文件列表id
        List<CourseRotation> rationList = rotationMapper.selectList(
                new QueryWrapper<CourseRotation>()
                        .select("file_id")
                        .eq("course_id", id));
        List<Integer> fileList = rationList.stream().map(CourseRotation::getFileId).collect(Collectors.toList());
        // 4.2 删除文件列表
        if (fileList.size() > 0) {
            fileMapper.deleteBatchIds(fileList);
        }
        // 4.3 删除课程关联轮播图表
        rotationMapper.delete(new QueryWrapper<CourseRotation>().eq("course_id", id));

        if (i <= 0) {
            return Result.fail("删除课程信息失败！");
        }
        return Result.success("删除课程信息成功！");
    }

    /**
     * 获取用户今日课程列表
     *
     * @param uid 用户 Id
     * @return 课程列表
     */
    @Override
    public Result getTodayCourseList(Integer uid) {
        return Result.success(
                courseMapper.getTodayCourseByUserId(
                        TimeUtil.getStartOfDay(new Date()),
                        TimeUtil.getEndOfDay(new Date()),
                        uid)
        );
    }

    /**
     * 获取用户所有课程列表
     *
     * @param uid 用户 Id
     * @return 课程列表
     */
    @Override
    public Result getStudentCourseList(Integer uid) {
        return Result.success(courseMapper.getTodayCourseByUserId(null,null,uid));
    }

    /**
     * 判断用户是否已购买该课程
     *
     * @param uid      用户id
     * @param courseId 课程id
     * @return 查询结果
     */
    @Override
    public Result checkStudentBuyCourseByUserId(Integer uid, Integer courseId) {
        return Result.success(orderMapper.checkStudentBuyCourseById(uid, courseId));
    }

    /**
     * 分角色获取课程列表
     *
     * @param uid 账户id
     * @return 课程列表
     */
    @Override
    public Result getCourseListByRole(Integer uid) {
        UserInfo teacher = teacherMapper.selectOne(
                new QueryWrapper<UserInfo>()
                        .eq("user_id", uid)
        );
        List<Course> list = null;
        if(Const.TEACHER_ROLE_CODE.equals(teacher.getRoleId())){
            // 教师
             list = courseMapper.getCourseListByRole(teacher.getId());
        } else {
            // 管理员
            list = courseMapper.getCourseListByRole(null);
        }
        return Result.success(list);
    }

    /**
     * 获取销量前五
     *
     * @return 数据
     */
    @Override
    public Result getCourseSales() {
        return Result.success(courseMapper.getCourseSales());
    }

    /**
     * 课程列表-不分页
     */
    @Override
    public Result getCourseList() {
        List<Course> list = courseMapper.geCourseList();
        if(list.size() > 0) {
            return Result.success(list);
        }
        return Result.fail("课程数据为空！");
    }

    /**
     * 添加课程
     *
     * @param course 新建课程信息
     * @return 结果
     */
    @Override
    public Result addCourse(Course course) throws CommonException {
        // 1、获取课程上课时间、教师列表、轮播图列表
        List<CourseTime> timeList = course.getClassTime();
        List<UserInfo> teacherList = course.getTeacherList();
        List<FileResources> rotationList = course.getRotationList();

        // 2、创建课程时，课程容量与课程余量相等
        course.setSurplus(course.getCapacity());

        // 3、保存课程信息
        if (courseMapper.insert(course) <= 0) {
            log.error("插入课程出错！");
            return Result.fail("服务器内部错误");
        }

        // 4、存储课程教师信息
        for (UserInfo teacher: teacherList) {
            teacher.setCourseId(course.getId());
            Integer insert = courseTeacherMapper.insert(teacher);
            if (insert <= 0) {
                log.error("存储课程教师出错！");
                return Result.fail("服务器内部错误");
            }
        }

        // 5、存上课时间
        for (CourseTime time : timeList) {
            time.setCourseId(course.getId());
            if (timeMapper.insert(time) <= 0) {
                courseMapper.deleteById(course.getId());
                log.error("插入课程时间出错！");
                return Result.fail("服务器内部错误");
            }
        }

        // 6、存储轮播图信息
        insertRatation(rotationList, course);

        return Result.success("添加课程成功！");
    }

    /**
     * 更新课程
     *
     * @param course 更新课程信息
     * @return 结果
     */
    @Override
    public Result updateCourse(Course course) throws CommonException {
        // 1、获取课程上课时间列表 、 教师列表 、轮播图列表
        List<CourseTime> newTimeList = course.getClassTime();
        List<UserInfo> newTeacherList = course.getTeacherList();
        List<FileResources> rotationList = course.getRotationList();

        // 2、更新课程信息
        if (courseMapper.updateById(course) <= 0) {
            log.error("更新课程出错！");
            return Result.fail("服务器内部错误");
        }

        // 3、更新教师列表
        // 3.1 删除教师信息
        courseTeacherMapper.deleteByCourseId(course.getId());
        // 3.2 插入课程关联教师信息
        for (UserInfo teacher: newTeacherList) {
            teacher.setCourseId(course.getId());
            Integer insert = courseTeacherMapper.insert(teacher);
            if (insert <= 0) {
                log.error("更新课程教师出错！");
                return Result.fail("服务器内部错误");
            }
        }

        // 4、更新课时信息
        // 4.1 删除原来所有课时信息
        timeMapper.delete(
                new QueryWrapper<CourseTime>()
                        .eq("course_id", course.getId()));
        // 4.2 更新课时信息
        for (CourseTime time : newTimeList) {
            time.setCourseId(course.getId());
            if (timeMapper.insert(time) <= 0) {
                log.error("更新课时信息出错！");
                return Result.fail("服务器内部错误");
            }
        }

        rotationMapper.delete(
                new QueryWrapper<CourseRotation>()
                        .eq("course_id", course.getId())
        );
        // 5、存储轮播图信息
        insertRatation(rotationList, course);

        return Result.success("更新课程成功！");
    }

    /**
     * 根据id 获取课程信息
     *
     * @param id 课程id
     * @return 课程信息
     */
    @Override
    public Result getCourseById(@NotNull(message = "课程id不能为空") Integer id) {
        Course course = courseMapper.getCourseById(id);
        if(course == null) {
            return Result.fail("课程信息不存在！");
        }
        return Result.success(course);
    }

    /**
     * 获取课程年龄段列表
     *
     * @return 年龄段列表
     */
    @Override
    public Result getAgeList() {
        List<String> list = courseMapper.getAgeList();
        if(list.size() <= 0){
            return Result.success("适合年龄段为空！");
        }
        return Result.success(list);
    }

    /**
     * 获取课程分类列表
     *
     * @return 课程分类列表
     */
    @Override
    public Result getTypeList() {
        List<String> list = courseMapper.getClassifyList();
        if(list.size() <= 0){
            return Result.success("课程分类为空！");
        }
        return Result.success(list);
    }

    /**
     * 插入轮播图信息
     * @param rotationList 轮播图列表
     * @param course 课程信息
     */
    private void insertRatation(List<FileResources> rotationList, Course course) throws CommonException {
        for (FileResources file: rotationList) {
            CourseRotation rotation = new CourseRotation();
            rotation.setFileId(file.getId());
            rotation.setCourseId(course.getId());
            if (rotationMapper.insert(rotation) <= 0) {
                log.error("插入课程轮播图出错！");
                throw new CommonException("服务器内部错误");
            }
        }
    }
}
